package com.ctgu.chatapp.Netty.Handler

import com.ctgu.chatapp.Netty.NettyClient
import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelInboundHandlerAdapter
import java.util.concurrent.TimeUnit


@Sharable
class ReconnectHandler(private val nettyClient: NettyClient) : ChannelInboundHandlerAdapter() {
    private var retries = 0
    private var retryPolicy: RetryPolicy? = null
        get() {
            if (field == null) {
                field = nettyClient.retryPolicy
            }
            return field
        }


    @Throws(Exception::class)
    override fun channelActive(ctx: ChannelHandlerContext) {
        println("Successfully established a connection to the server.")
        retries = 0
        ctx.fireChannelActive()
    }

    @Throws(Exception::class)
    override fun channelInactive(ctx: ChannelHandlerContext) {
        if (retries == 0) {
            System.err.println("Lost the TCP connection with the server.")
            ctx.close()
        }
        val allowRetry = retryPolicy!!.allowRetry(retries)
        if (allowRetry) {
            val sleepTimeMs = retryPolicy!!.getSleepTimeMs(retries)
            println(
                String.format(
                    "Try to reconnect to the server after %dms. Retry count: %d.",
                    sleepTimeMs,
                    ++retries
                )
            )
            val eventLoop = ctx.channel().eventLoop()
            eventLoop.schedule({
                println("Reconnecting ...")
                nettyClient.connect()
            }, 1000, TimeUnit.MILLISECONDS)
        }
        ctx.fireChannelInactive()
    }
}